/* 
  2012.1.1
  2012.1.8 - add
  Lee SoHaeng
*/

#include <stdint.h>

typedef unsigned char   Uchar;
typedef unsigned short  Uint;
typedef unsigned int    Ulong; 
typedef Ulong *         UlongP; 

// RCC define
#define RCC_APB2ENR             (*(volatile unsigned *)0x40021018) /*reset & clock control */
#define RCC_APB2PERIPH_AFIO     ((Ulong)0x00000001)
#define RCC_APB2PERIPH_GPIOA    ((Ulong)0x00000004)
#define RCC_APB2PERIPH_GPIOB    ((Ulong)0x00000008)
#define RCC_APB2PERIPH_GPIOC    ((Ulong)0x00000010)
#define RCC_APB2PERIPH_GPIOD    ((Ulong)0x00000020)
#define RCC_APB2PERIPH_GPIOE    ((Ulong)0x00000040)
#define RCC_APB2PERIPH_GPIOF    ((Ulong)0x00000080)
#define RCC_APB2PERIPH_GPIOG    ((Ulong)0x00000100)
#define RCC_APB2PERIPH_ADC1     ((Ulong)0x00000200)
#define RCC_APB2PERIPH_ADC2     ((Ulong)0x00000400)
#define RCC_APB2PERIPH_TIM1     ((Ulong)0x00000800)
#define RCC_APB2PERIPH_SPI1     ((Ulong)0x00001000)
#define RCC_APB2PERIPH_TIM8     ((Ulong)0x00002000)
#define RCC_APB2PERIPH_USART1   ((Ulong)0x00004000)
#define RCC_APB2PERIPH_ADC3     ((Ulong)0x00008000)

// GPIO pin define
#define GPIO_PIN_0              ((Uint)0x0001) 
#define GPIO_PIN_1              ((Uint)0x0002) 
#define GPIO_PIN_2              ((Uint)0x0004) 
#define GPIO_PIN_3              ((Uint)0x0008) 
#define GPIO_PIN_4              ((Uint)0x0010) 
#define GPIO_PIN_5              ((Uint)0x0020) 
#define GPIO_PIN_6              ((Uint)0x0040) 
#define GPIO_PIN_7              ((Uint)0x0080) 
#define GPIO_PIN_8              ((Uint)0x0100) 
#define GPIO_PIN_9              ((Uint)0x0200) 
#define GPIO_PIN_10             ((Uint)0x0400)
#define GPIO_PIN_11             ((Uint)0x0800) 
#define GPIO_PIN_12             ((Uint)0x1000) 
#define GPIO_PIN_13             ((Uint)0x2000) 
#define GPIO_PIN_14             ((Uint)0x4000) 
#define GPIO_PIN_15             ((Uint)0x8000) 
#define GPIO_PIN_ALL            ((Uint)0xFFFF) 

// GPIOB define
#define GPIOB_BSRR              (*(volatile Ulong *)0x40010C10)
#define GPIOB_BRR               (*(volatile Ulong *)0x40010C14)
#define GPIOB_CRL               (*(volatile Ulong *)0x40010C00)
#define GPIOB_CRH               (*(volatile Ulong *)0x40010C04)

#define GPIO_LED1_PIN           GPIO_PIN_5   /* YELLOW */
#define GPIO_LED2_PIN           GPIO_PIN_9   /* RED */
#define GPIO_LED3_PIN           GPIO_PIN_8   /* GREEN/BLUE */

// set clock
#define GPIO_SPEED_10MHz        1
#define GPIO_SPEED_2MHz         2
#define GPIO_SPEED_50MHz        3

// GPIOC define
#define GPIOC_BSRR              (*(volatile Ulong *)0x40011010)
#define GPIOC_BRR               (*(volatile Ulong *)0x40011014)
#define GPIOC_CRL               (*(volatile Ulong *)0x40011000)
#define GPIOC_CRH               (*(volatile Ulong *)0x40011004)

#define GPIO_7_SEG_A            GPIO_PIN_0
#define GPIO_7_SEG_B            GPIO_PIN_1
#define GPIO_7_SEG_C            GPIO_PIN_2
#define GPIO_7_SEG_D            GPIO_PIN_3
#define GPIO_7_SEG_E            GPIO_PIN_4
#define GPIO_7_SEG_F            GPIO_PIN_5
#define GPIO_7_SEG_G            GPIO_PIN_7
#define GPIO_7_SEG_DP           GPIO_PIN_6
#define GPIO_7_SEG_PW           GPIO_PIN_8

/*-----------------------------------------------------------------
    struct
    typedef
    enum
-------------------------------------------------------------------*/

#define _IO               volatile
#define PERIPH_BASE       ((Ulong)0x40000000)
#define APB1PERIPH_BASE   PERIPH_BASE
#define APB2PERIPH_BASE   (PERIPH_BASE + 0x00010000)
#define AHBPERIPH_BASE    (PERIPH_BASE + 0x00020000)
#define RCC_BASE          (AHBPERIPH_BASE + 0x00001000)
#define USART1_BASE       (APB2PERIPH_BASE + 0x3800)
#define USART1            ((USART_TypeDef *)USART1_BASE)
#define GPIOUSART         GPIOA
#define GPIO_USART_Rx_PIN GPIO_PIN_10
#define GPIO_USART_Tx_PIN GPIO_PIN_9
  
// RCC type define
typedef struct {
    _IO Ulong  CR;
    _IO Ulong  CFGR;
    _IO Ulong  CIR;
    _IO Ulong  APB2RSTR;
    _IO Ulong  APB1RSTR;
    _IO Ulong  AHBENR;
    _IO Ulong  APB2ENR;
    _IO Ulong  APB1ENR;
    _IO Ulong  BDCR;
    _IO Ulong  CSR;  
}RCC_TypeDef;

#define RCC               ((RCC_TypeDef *)RCC_BASE)

// GPIO type define
typedef struct {
    _IO Ulong  CRL;
    _IO Ulong  CRH;
    _IO Ulong  IDR;
    _IO Ulong  ODR;
    _IO Ulong  BSRR;
    _IO Ulong  BRR;
    _IO Ulong  LCKR;    
}GPIO_TypeDef;

#define GPIOA_BASE        (APB2PERIPH_BASE + 0x0800)
#define GPIOB_BASE        (APB2PERIPH_BASE + 0x0C00)
#define GPIOC_BASE        (APB2PERIPH_BASE + 0x1000)
#define GPIOD_BASE        (APB2PERIPH_BASE + 0x1400)
#define GPIOE_BASE        (APB2PERIPH_BASE + 0x1800)
#define GPIOF_BASE        (APB2PERIPH_BASE + 0x1C00)
#define GPIOG_BASE        (APB2PERIPH_BASE + 0x2000)

#define GPIOA             ((GPIO_TypeDef *)GPIOA_BASE)
#define GPIOB             ((GPIO_TypeDef *)GPIOB_BASE)
#define GPIOC             ((GPIO_TypeDef *)GPIOC_BASE)
#define GPIOD             ((GPIO_TypeDef *)GPIOD_BASE)
#define GPIOE             ((GPIO_TypeDef *)GPIOE_BASE)
#define GPIOF             ((GPIO_TypeDef *)GPIOF_BASE)
#define GPIOG             ((GPIO_TypeDef *)GPIOG_BASE)

// Speed define
typedef enum {
    GPIO_Input_Mode = 0,    
    GPIO_Speed_10MHz,
    GPIO_Speed_2MHz,
    GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;

// input mode define
typedef enum
{
    Bit_RESET = 0,
    Bit_SET
} BitAction;

typedef enum
{
    RESET = 0,
    SET = !RESET
} FlagStatus;

typedef enum
{
    DISABLE = 0,
    ENABLE = !DISABLE
} FunctionalState;

typedef enum {
    GPIO_MODE_AIN = 0x0,
    GPIO_MODE_IN_FLOATING = 0x04,
    GPIO_MODE_IPD = 0x28,
    GPIO_MODE_IPU = 0x48,
    GPIO_MODE_OUT_OD = 0x14,
    GPIO_MODE_OUT_PP = 0x10,
    GPIO_MODE_AF_OD = 0x1C,
    GPIO_MODE_AF_PP = 0x18      
}GPIOMode_TypeDef;

typedef struct {
    Uint                  GPIO_PIN;
    GPIOSpeed_TypeDef     GPIO_SPEED;
    GPIOSpeed_TypeDef     GPIO_MODE;
}GPIO_InitTypeDef;

typedef struct {
    _IO Uint SR;   //2 byte
    _IO Uint RVD0;
    _IO Uint DR;
    _IO Uint RVD1;
    _IO Uint BRR;
    _IO Uint RVD2;
    _IO Uint CR1;
    _IO Uint RVD3;
    _IO Uint CR2;
    _IO Uint RVD4;
    _IO Uint CR3;
    _IO Uint RVD5;
    _IO Uint GTPR;
    _IO Uint RVD6;
}USART_TypeDef;

typedef struct {
    Ulong   USART_BAUDRATE;
            /*  DIV_Mantissa = USARTDIV * 16
                DIV_Fraction = (USARTDIV - (Uint)USARTDIV) * 16 + 0.5
            */
    Uint    USART_WORDLENGTH;
    Uint    USART_STOPBITS;
    Uint    USART_PARITY;
    Uint    USART_MODE;
    Uint    USART_HARDWAREFLOWCONTROL;
}USART_InitTypeDef;

// Word Length
#define USART_WORDLENGTH_8B             ((Uint)0x0000)
#define USART_WORDLENGTH_9B             ((Uint)0x1000)

// Stop bits
#define USART_STOPBITS_1                ((Uint)0x0000)
#define USART_STOPBITS_0_5              ((Uint)0x1000)
#define USART_STOPBITS_2                ((Uint)0x2000)
#define USART_STOPBITS_1_5              ((Uint)0x3000)

// Parity bits
#define USART_PARITY_NO                 ((Uint)0x0000)
#define USART_PARITY_EVEN               ((Uint)0x0400)
#define USART_PARITY_ODD                ((Uint)0x0600)

// Hardware Flow Control
#define USART_HARDWAREFLOWCONTROL_NONE     ((Uint)0x0000)
#define USART_HARDWAREFLOWCONTROL_RTS      ((Uint)0x0100)
#define USART_HARDWAREFLOWCONTROL_CTS      ((Uint)0x0200)
#define USART_HARDWAREFLOWCONTROL_RTS_CTS  ((Uint)0x0300)

// Mode
#define USART_MODE_Rx     ((Uint)0x0004)
#define USART_MODE_Tx     ((Uint)0x0008)

// CR1_UE_Set
#define CR1_UE_SET            ((Uint)0x2000)  // USART Enable mask
#define HSI_VALUE             ((Ulong)8000000) // 8MHz
#define CR1_CLEAR_MASK        ((Uint)0xE9F3)
#define CR2_STOP_CLEAR_MASK   ((Uint)0xCFFF) // 1100111111111111
#define CR3_CLEAR_MASK        ((Uint)0xFCFF) // 1111110011111111

#define USART_FLAG_TXE        ((Uint)0x0080)




// define prototype
void Port_Init(GPIO_TypeDef *      GPIOx, 
               Uint                pNum, 
               GPIOSpeed_TypeDef   speed,
               Uint                mode);
              
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct, Uchar *s);
void PtrNum2PortC(unsigned n);
void delaycnt();

void USART_SendData(USART_TypeDef * usart, Uint Data);
FlagStatus USART_GetFlagStatus(USART_TypeDef * usart, Uint USART_FLAG);
void SerialPutChar( Uchar c );
void Serial_PutString(Uchar *s);
void USART_Set(USART_TypeDef *usart, USART_InitTypeDef *type);
void USART_Init();